/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.graph.Model', {
	init: function(canvas, modelConfig) {
		var me = this, model = canvas.paper[modelConfig.type]().attr(modelConfig.attrs),
				config = {
					flowFrom: modelConfig.type === 'path' ? null : [],
					flowTo: modelConfig.type === 'path' ? null : [],
					canvas: canvas, coreX: 0, coreY: 0
				};
		model.id = model.node.raphaelid = canvas.createId(canvas, model.type, modelConfig.modelId);
		if (!model.data('modelType')) {
			var data = modelConfig.data, graph = canvas.locale.canvasPanel.graph[modelConfig.type], modelType;
			if (data) {
				modelType = data.modelType
			} else if (graph) {
				modelType = graph.modelType;
			}
			if (modelType) {
				model.data('modelType', modelType);
			}
		}
		model.data(modelConfig.data);
		Ext.apply(model, config);
		if (!canvas.readOnly) {
			model.drag(me.onDDMove, me.onDDStart, me.onDDEnd);
		}
		var bbox = model.getBBox();
		model.coreX = bbox.cx;
		model.coreY = bbox.cy;
		if (modelConfig.text) {
			var text = canvas.paper.text().attr(modelConfig.text.attrs);
			model.text = text;
			text.model = model;
			var bbox = text.getBBox();
			text.coreX = bbox.cx;
			text.coreY = bbox.cy;
		}
		return model;
	},
	onDDStart: function(x, y, e) {
		var model = this, canvas = model.canvas, selectBox = canvas.selectBox,
				lineX = canvas.lineX, pathX = lineX.attrs.path,
				lineY = canvas.lineY, pathY = lineY.attrs.path;
		lineX.show();
		lineY.show();
		selectBox.oldX = selectBox.attrs.x;
		selectBox.oldY = selectBox.attrs.y;
		pathX[0][1] = pathX[1][1] = -10;
		lineX.attr({path: pathX});
		pathY[0][2] = pathY[1][2] = -10;
		lineY.attr({path: pathY});
	},
	onDDMove: function(dx, dy, x, y, e) {
		var model = this, canvas = model.canvas, selectBox = canvas.selectBox,
				lineX = canvas.lineX, pathX = lineX.attrs.path,
				lineY = canvas.lineY, pathY = lineY.attrs.path,
				newX = selectBox.oldX + dx, newY = selectBox.oldY + dy;
		newX = Raphael.snapTo(5, newX);
		newY = Raphael.snapTo(5, newY);
		selectBox.attr({x: newX, y: newY});
		pathX[0][1] = pathX[1][1] = selectBox.attrs.x + selectBox.attrs.width / 2;
		lineX.attr({path: pathX});
		pathY[0][2] = pathY[1][2] = selectBox.attrs.y + selectBox.attrs.height / 2;
		lineY.attr({path: pathY});
		if (!canvas.widget.isHidden()) {
			canvas.widget.hide();
		}
	},
	onDDEnd: function(x, y, e) {
		var model = this, canvas = model.canvas, selectBox = canvas.selectBox;
		var offsetX = selectBox.attrs.x - selectBox.oldX,
				offsetY = selectBox.attrs.y - selectBox.oldY;
		if (offsetX != 0 || offsetY != 0) {
			Ext.each(canvas.selected, function(model) {
				if (model.type === 'circle' || model.type === 'ellipse') {
					model.oldX = model.attrs.cx;
					model.oldY = model.attrs.cy;
					model.attr({cx: model.oldX + offsetX, cy: model.oldY + offsetY});
				} else {
					model.oldX = model.attrs.x;
					model.oldY = model.attrs.y;
					model.attr({x: model.oldX + offsetX, y: model.oldY + offsetY});
				}
				var bbox = model.getBBox();
				model.coreX = bbox.cx;
				model.coreY = bbox.cy;
				if (model.text) {
					model.text.attr({x: model.coreX, y: bbox.y2 + 10});
				}
				Ext.each(model.flowFrom, function(ff) {
					var oldCoreStart = ff.start, path = ff.attrs.path;
					if (ff.flowFrom) {
						oldCoreStart = [ff.flowFrom.coreX, ff.flowFrom.coreY];
						path[0] = ['M', oldCoreStart[0], oldCoreStart[1]];
					}
					if (path.length > 2) {
						if (Ext.Array.contains(canvas.selected, ff.flowFrom)) {
							Ext.each(path, function(point) {
								point[1] += offsetX;
								point[2] += offsetY;
							});
						} else {
							for (var i = 1; i < path.length - 1; i++) {
								if (model.isPointInside(path[i][1], path[i][2])) {
									Ext.Array.remove(path, path[i]);
									i--;
								}
							}
//							if (path[len - 2][1] == path[len - 1][1]) {
//								path[len - 2][1] += offsetX;
//							}
//							if (path[len - 2][2] == path[len - 1][2]) {
//								path[len - 2][2] += offsetY;
//							}
						}
					}
					path[path.length - 1] = ['L', model.coreX, model.coreY];
					ff.attr({path: path});
					canvas.connect(ff);
				});
				Ext.each(model.flowTo, function(ft) {
					var oldCoreEnd = ft.end, path = ft.attrs.path;
					if (ft.flowTo) {
						oldCoreEnd = [ft.flowTo.coreX, ft.flowTo.coreY];
						path[path.length - 1] = ['L', oldCoreEnd[0], oldCoreEnd[1]];
					}
					if (path.length > 2) {
						if (!Ext.Array.contains(canvas.selected, ft.flowTo)) {
							for (var i = 1; i < path.length - 1; i++) {
								if (model.isPointInside(path[i][1], path[i][2])) {
									Ext.Array.remove(path, path[i]);
									i--;
								}
							}
//							if (path[1][1] == path[0][1]) {
//								path[1][1] += offsetX;
//							}
//							if (path[1][2] == path[0][2]) {
//								path[1][2] += offsetY;
//							}
						}
					}
					path[0] = ['M', model.coreX, model.coreY];
					ft.attr({path: path});
					canvas.connect(ft);
				});
			});
		}
		canvas.lineX.hide();
		canvas.lineY.hide();
	}
});